#!/bin/sh
set -e

PIPEFILE=/tmp/gtkserver.gtk.$$

die() {
  echo "$@"
  exit 1
}


gtk() {
  echo $@ > $PIPEFILE
  read GTK < $PIPEFILE
  echo "$GTK"
}

gtkq() {
  gtk "$@" >&2
}

gtke() {
  RESULT="$(gtk "$@")"
  [ "$RESULT" = -1 ] && die "Failed to run: $@"
  echo "$RESULT"
}

gtkinit() {
  gtk-server-gtk3 -fifo=$PIPEFILE -detach >&2
  while ! [ -p $PIPEFILE ]; do continue; done
  gtkq "gtk_init NULL NULL"
}

searchwidget() {
  TEXTLABEL="$1"
  LAB="$(gtk "gtk_label_new "$TEXTLABEL"")"
  LIST="$(gtke "gtk_list_store_new 1 G_TYPE_STRING")"
  TREE="$(gtke "gtk_tree_view_new_with_model $LIST")"
  SEL="$(gtke "gtk_tree_view_get_selection $TREE")"
  gtkq "gtk_tree_selection_set_mode $SEL GTK_SELECTION_SINGLE"
  gtkq "gtk_tree_view_set_grid_lines $TREE 3"
  RENDERER1="$(gtke "gtk_cell_renderer_text_new")"
  COLUMN1="$(gtke "gtk_tree_view_column_new_with_attributes "Results" $RENDERER1 'text' 0 NULL")"
  gtkq "gtk_tree_view_append_column $TREE $COLUMN1"
  gtkq "gtk_server_redefine gtk_list_store_new NONE WIDGET 2 INT INT"
  SW="$(gtke "gtk_scrolled_window_new NULL NULL")"
  gtkq "gtk_scrolled_window_set_policy $SW 1 1"
  gtkq "gtk_scrolled_window_set_shadow_type $SW 1"
  gtkq "gtk_container_add $SW $TREE"
  ENTRY="$(gtke "gtk_entry_new")"
  gtkq "gtk_server_define gtk_table_new NONE WIDGET 3 LONG LONG BOOL"
  TABLE="$(gtk "gtk_table_new 10 10 1")"
  BUTTON="$(gtke "gtk_button_new_with_label 'Search'")"
  gtkq "gtk_table_attach_defaults $TABLE $LAB 0 10 0 1"
  gtkq "gtk_table_attach_defaults $TABLE $SW 0 10 2 9"

  gtkq "gtk_table_attach_defaults $TABLE $ENTRY 0 10 1 2"
  gtkq "gtk_table_attach_defaults $TABLE $BUTTON 0 10 9 10"
  echo "$TABLE $TREE $LIST $BUTTON $ENTRY"
}

gotable() {
  GO_TABLE="$(gtk "gtk_table_new 10 1 1")"
  GO_LABEL="$(gtke "gtk_label_new ''")"
  gtkq "gtk_table_attach_defaults $GO_TABLE $GO_BUTTON 9 10 1 2"
  echo "$GO_TABLE $GO_BUTTON"
}

curlnominatim() {
  QUERY="$1"
  NOM_ENDPOINT="https://nominatim.openstreetmap.org/search"
  curl \
    --get \
    --data-urlencode "q=$QUERY" \
    --data-urlencode "format=json" \
    "${NOM_ENDPOINT}" |
    jq '.[] | "\(.display_name) \(.lat) \(.lon)" '
}

search() {
  STATUSLABEL="$1"
  LIST="$2"
  ENTRY="$3"

  gtkq "gtk_list_store_clear $LIST"
  QUERY="$(gtke "gtk_entry_get_text $ENTRY")"
  #gtkq "gtk_label_set_text $STATUSLABEL 'Searching...'"
  RESULTS="$(curlnominatim "$QUERY")"
  ITER="$(gtke "gtk_server_opaque")"
  gtkq "gtk_server_redefine gtk_list_store_set NONE NONE 5 WIDGET WIDGET INT STRING INT"
  echo "$RESULTS" | while read RESULT; do
    echo "$RESULT" | grep -q . || continue
    gtkq "gtk_list_store_append $LIST $ITER"
    gtkq "gtk_list_store_set $LIST $ITER 0 "$RESULT" -1"
  done
  #gtkq "gtk_label_set_text $STATUSLABEL ''"

  echo "$RESULTS"
}

run() {
  NENTRIES=$1
  if echo $NENTRIES | grep -vEq '[0-9]'; then
    NENTRIES=1
  fi
  
  gtkinit

  # Create Search A component
  SEARCHA="$(searchwidget "From:")"
  SEARCHA_TABLE="$(echo $SEARCHA | cut -d' ' -f1)"
  SEARCHA_TREE="$(echo $SEARCHA | cut -d' ' -f2)"
  SEARCHA_LIST="$(echo $SEARCHA | cut -d' ' -f3)"
  SEARCHA_BUTTON="$(echo $SEARCHA | cut -d' ' -f4)"
  SEARCHA_ENTRY="$(echo $SEARCHA | cut -d' ' -f5)"

  # Create go / submit row table
  GO_BUTTON="$(gtke "gtk_button_new_with_label 'Submit'")"

  gtkq "gtk_server_define gtk_box_new NONE WIDGET 2 ENUM INT"
  BOX="$(gtke gtk_box_new 1 20)"
  gtkq "gtk_container_set_border_width $BOX 20"
  gtkq "gtk_box_pack_start $BOX $SEARCHA_TABLE 1 1 0"
  gtkq "gtk_box_pack_end $BOX $GO_BUTTON 0 0 0"

  if [ $NENTRIES = 2 ]; then
    # Create Search B component
    SEARCHB="$(searchwidget "To:")"
    SEARCHB_TABLE="$(echo $SEARCHB | cut -d' ' -f1)"
    SEARCHB_TREE="$(echo $SEARCHB | cut -d' ' -f2)"
    SEARCHB_LIST="$(echo $SEARCHB | cut -d' ' -f3)"
    SEARCHB_BUTTON="$(echo $SEARCHB | cut -d' ' -f4)"
    SEARCHB_ENTRY="$(echo $SEARCHB | cut -d' ' -f5)"
    gtkq "gtk_box_pack_end $BOX $SEARCHB_TABLE 1 1 0"
  fi

  WIN="$(gtke "gtk_window_new 0")"
  gtkq "gtk_window_set_resizable $WIN 1"
  gtkq "gtk_window_set_title $WIN 'Mobroute from/to'"
  gtkq "gtk_container_add $WIN $BOX"
  gtkq "gtk_widget_show_all $WIN"

  CONTINUE=1
  SEARCHA_RESULTS=""
  SEARCHB_RESULTS=""
  while [ $CONTINUE = 1 ]; do 
    EVENT="$(gtke "gtk_server_callback WAIT")"
    case $EVENT in
      $GO_BUTTON) CONTINUE=0;;
      $SEARCHA_ENTRY|$SEARCHA_BUTTON) SEARCHA_RESULTS="$(search foo $SEARCHA_LIST $SEARCHA_ENTRY)";;
      $SEARCHB_ENTRY|$SEARCHB_BUTTON) SEARCHB_RESULTS="$(search foo $SEARCHB_LIST $SEARCHB_ENTRY)";;
    esac        
  done

  PRINT=""

  ITER="$(gtke "gtk_server_opaque")"
  SEL="$(gtk "gtk_tree_view_get_selection $SEARCHA_TREE")"
  HASSEL="$(gtk "gtk_tree_selection_get_selected $SEL NULL $ITER")"
  ROWN="$(gtke "gtk_tree_model_get_string_from_iter $SEARCHA_LIST $ITER" | xargs -IN echo N + 1 | bc)"
  PRINT="${PRINT}$(echo "$SEARCHA_RESULTS" | sed -n ${ROWN}p)"

  if [ $NENTRIES = 2 ]; then
    ITER="$(gtke "gtk_server_opaque")"
    SEL="$(gtk "gtk_tree_view_get_selection $SEARCHB_TREE")"
    HASSEL="$(gtk "gtk_tree_selection_get_selected $SEL NULL $ITER")"
    ROWN="$(gtke "gtk_tree_model_get_string_from_iter $SEARCHB_LIST $ITER" | xargs -IN echo N + 1 | bc)"
    PRINT="${PRINT}\n$(echo "$SEARCHB_RESULTS" | sed -n ${ROWN}p)"
  fi

  gtkq "gtk_server_exit"
  printf %b "$PRINT"
  kill $$
}

run $1
